#include <stdio.h>
#include <string.h>
#include "Version.h"

// 应用程序信息结构体定义
// 包含版本信息、构建日期时间等所有版本相关数据
typedef struct{
    uint8 AppVersion[16];           // 应用程序版本信息
    uint8 App_Build_Date[11];       // 应用程序构建日期
    uint8 App_Build_Time[8];        // 应用程序构建时间
} AppInformation;

/*==============================================================================
=======                 VARIABLES & MESSAGES & RESOURCES                 =======
==============================================================================*/
// 条件编译：仅在Green Hills编译器下使用特定段声明
#ifdef __ghs__
#pragma ghs section rodata=".AppVersion"
#endif

// 应用程序信息常量实例
// 存储所有版本相关信息，包括版本号、构建日期和时间等
static const AppInformation AppInfo = {
    /* AppVersion              */ { SWP_VERSION },                   // 应用程序版本
    /* App_Build_Date          */ { __DATE__ },                      // 编译器生成的构建日期
    /* App_Build_Time          */ { __TIME__ },                      // 编译器生成的构建时间
 
};

// 条件编译结束
#ifdef __ghs__
// #pragma ghs section rodata=default
#endif

// 月份索引数组大小定义
#define VPU_MONTH_MAX_INDEX (12)

// 月份名称索引数组
// 用于将编译器生成的月份字符串转换为数字格式
char* MonthIndex[VPU_MONTH_MAX_INDEX] =
{
    "Jan",  // 一月
    "Feb",  // 二月
    "Mar",  // 三月
    "Apr",  // 四月
    "May",  // 五月
    "Jun",  // 六月
    "Jul",  // 七月
    "Aug",  // 八月
    "Sep",  // 九月
    "Oct",  // 十月
    "Nov",  // 十一月
    "Dec"   // 十二月
};

/*==============================================================================
=======                             METHODS                              =======
==============================================================================*/

/**
 * @brief 获取构建日期信息
 * 
 * 从编译器生成的日期字符串(__DATE__)中提取年、月、日信息，
 * 并将其格式化为特定格式存储在Date_InfoType结构体中。
 * 
 * @param date 指向Date_InfoType结构体的指针，用于存储日期信息
 * @return uint8 返回操作结果，TRUE表示成功，FALSE表示失败
 */
uint8 Vpu_GetBuildDate(Date_InfoType *date)
{
    uint8 index = 0;      // 月份索引
    uint8 month;          // 月份数值

    // 检查输入参数有效性
    if(NULL == date)
    {
        return FALSE;
    }

    // 遍历月份索引数组，查找匹配的月份
    for (index=0; index<VPU_MONTH_MAX_INDEX; index++)
    {
        // 使用strstr函数查找当前月份是否匹配
        if (strstr(__DATE__, MonthIndex[index]) != NULL)
        {
            // 提取年份信息（从__DATE__的第7-10个字符）
            date->year[0] = __DATE__[7];
            date->year[1] = __DATE__[8];
            date->year[2] = __DATE__[9];
            date->year[3] = __DATE__[10];

            // 计算月份数值（索引+1）
            month = index + 1;
            // 将月份转换为两位数字符串格式
            date->month[0] = '0' + (month / 10);
            date->month[1] = '0' + (month % 10);

            // 处理日期（天数）
            // 如果第4个字符是空格，则用'0'填充，否则直接使用原字符
            date->day[0] = ( (' ' == __DATE__[4]) ? '0' : __DATE__[4] );
            date->day[1] = __DATE__[5];

            // 找到匹配月份后退出循环
            break;
        }
    }

    // 如果没有找到匹配的月份，返回失败
    if(index >= VPU_MONTH_MAX_INDEX)
    {
        return FALSE;
    }
    
    // 成功获取日期信息
    return TRUE;
}

/**
 * @brief 获取构建时间信息
 * 
 * 从编译器生成的时间字符串(__TIME__)中提取时、分、秒信息，
 * 并将其存储在Time_InfoType结构体中。
 * 
 * @param time 指向Time_InfoType结构体的指针，用于存储时间信息
 * @return uint8 返回操作结果，TRUE表示成功，FALSE表示失败
 */
uint8 Vpu_GetBuildTime(Time_InfoType *time)
{
    // 检查输入参数有效性
    if(NULL == time)
    {
        return FALSE;
    }

    // 将AppInfo中的构建时间信息复制到输出参数中
    memcpy(&(time->time[0]), &(AppInfo.App_Build_Time[0]), sizeof(time->time));

    // 成功获取时间信息
    return TRUE;
}

/**
 * @brief 获取应用程序版本信息
 * 
 * 将存储在AppInfo中的应用程序版本信息复制到指定的结构体中。
 * 
 * @param appversion 指向AppVersion_InfoType结构体的指针，用于存储版本信息
 * @return uint8 返回操作结果，TRUE表示成功，FALSE表示失败
 */
uint8 Vpu_GetAppVersion(AppVersion_InfoType *appversion)
{
    // 检查输入参数有效性
    if(NULL == appversion)
    {
        return FALSE;
    }

    // 将AppInfo中的应用程序版本信息复制到输出参数中
    memcpy(&appversion->version[0], &AppInfo.AppVersion[0], sizeof(appversion->version));
    
    // 成功获取版本信息
    return TRUE;
}

/**
 * @brief 显示版本信息演示函数
 * 
 * 该函数用于打印应用程序的版本信息，包括构建日期、构建时间和应用程序版本。
 * 通过调用相应的VPU接口获取并显示这些信息，如果获取失败则显示错误提示信息。
 * 
 * @return int 返回操作状态，目前总是返回0
 */
// int version_demo() {
//     printf("=== Version Information ===\n");
    
//     // 获取并显示构建日期信息
//     Date_InfoType buildDate;
//     if (Vpu_GetBuildDate(&buildDate)) {
//         printf("Build Date: %.4s-%.2s-%.2s\n", buildDate.year, buildDate.month, buildDate.day);
//     } else {
//         printf("Build Date: Failed to retrieve\n");
//     }
    
//     // 获取并显示构建时间信息
//     Time_InfoType buildTime;
//     if (Vpu_GetBuildTime(&buildTime)) {
//         char timeStr[9];
//         memcpy(timeStr, buildTime.time, 8);
//         timeStr[8] = '\0';
//         printf("Build Time: %s\n", timeStr);
//     } else {
//         printf("Build Time: Failed to retrieve\n");
//     }
    
    // AppVersion_InfoType appVersion;
    // if (Vpu_GetAppVersion(&appVersion)) {
    //     // 应用程序版本是字符串，需要找到字符串结束位置
    //     int len=0;
    //     int max_len = sizeof(appVersion.version);
    //     for (len = 0; len < max_len && appVersion.version[len] != '\0'; len++);
    //     printf("App Version: %.*s\n", len, appVersion.version);
    // } else {
    //     printf("App Version: Failed to retrieve\n");
    // }
    
//     return 0;
// }
